package com.demo.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.demo.api.client.PermissionClient;
import com.demo.user.constants.JwtClaimsConstant;
import com.demo.user.context.BaseContext;
import com.demo.common.constants.RoleCode;
import com.demo.user.mapper.UserMapper;
import com.demo.user.pojo.dto.*;
import com.demo.user.pojo.entity.User;
import com.demo.user.pojo.vo.LoginVO;
import com.demo.user.pojo.vo.UserVO;
import com.demo.user.properties.JwtProperties;
import com.demo.user.result.PageResult;
import com.demo.user.result.Result;
import com.demo.user.service.IUserService;
import com.demo.user.utils.JwtUtil;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.transaction.annotation.ShardingSphereTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;


import java.util.*;



/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author hxt
 * @since 2025-06-16
 */
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final JwtProperties jwtProperties;
    private final PermissionClient permissionClient;
    /**
     *  用户注册
     * @param registerDTO 注册信息
     * @return 是否成功
     */
    @Transactional(rollbackFor = Exception.class)
    @ShardingSphereTransactionType(value = TransactionType.BASE)
    public Result<String> register(RegisterDTO registerDTO) {
        //查询是否存在相同用户名
        Integer count = lambdaQuery()
                .eq(User::getUsername, registerDTO.getUsername())
                .count();
        if (count > 0){
            return Result.error("用户名已存在");
        }
        //添加用户
        User user = new User();
        user.setUsername(registerDTO.getUsername());
        user.setPassword(DigestUtils.md5DigestAsHex(registerDTO.getPassword().getBytes()));
        user.setEmail(registerDTO.getEmail());
        user.setPhone(registerDTO.getPhone());
        save(user);
        //设置默认权限角色
        Long userId = user.getUserId();
        permissionClient.bindDefaultRole(userId);
        return Result.success("注册成功");
    }

    /**
     *  用户登录
     * @param loginDTO 登录信息
     * @return 登录结果
     */
    public Result login(LoginDTO loginDTO) {
        //获取用户信息
        User user = lambdaQuery()
                .eq(User::getUsername, loginDTO.getUsername())
                .eq(User::getPassword, DigestUtils.md5DigestAsHex(loginDTO.getPassword().getBytes()))
                .one();
        if (ObjectUtil.isNull(user)){
            return Result.error("用户名或密码错误");
        }
        //生成jwt
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USER_ID, user.getUserId());
        //获取角色权限
        Long userId =user.getUserId();
        String roleCode = permissionClient.getUserRoleCode(userId);
        claims.put(JwtClaimsConstant.USER_ROLE, roleCode);
        String jwt = JwtUtil.createJWT( jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);

        //封装vo并返回
        LoginVO loginVO = new LoginVO();
        loginVO.setToken(jwt);
        loginVO.setId(user.getUserId());
        loginVO.setUsername(user.getUsername());
        return Result.success(loginVO);
    }

    /**
     *  用户列表
     * @param pageQueryDTO 分页参数
     * @return 用户列表
     */
    public Result<PageResult> userPageQuery(PageQueryDTO pageQueryDTO) {
        //获取当前用户信息
        Map<String, Object> currentUser = BaseContext.getCurrentUser();
        Long userId = (Long) currentUser.get(JwtClaimsConstant.USER_ID);
        String roleCode = (String) currentUser.get(JwtClaimsConstant.USER_ROLE);
        //需要查询id的集合
        List<Long> userIds = new ArrayList<>();
        //添加自己的id
        userIds.add(userId);
        //根据不同的权限添加不同的用户id
        if (RoleCode.ADMIN.equalsIgnoreCase(roleCode)){
            //管理员可以查所有普通用户的信息
            List<String> roleCodes =Collections.singletonList(RoleCode.USER);
            userIds.addAll(permissionClient.getUserIdByRoleCodes(roleCodes));
        }else if (RoleCode.SUPER_ADMIN.equalsIgnoreCase(roleCode)){
            //超级管理员可以查所有用户信息
            List<String> roleCodes = Arrays.asList(RoleCode.USER, RoleCode.ADMIN, RoleCode.SUPER_ADMIN);
            userIds.addAll(permissionClient.getUserIdByRoleCodes(roleCodes));
        }
        //分页查询
        Page<User> page = new Page<>(pageQueryDTO.getPage(), pageQueryDTO.getPageSize());
        Page<User> result = lambdaQuery()
                .in(User::getUserId, userIds)
                .page(page);
        //封装并返回
        List<User> records = result.getRecords();
        List<UserVO> userVOS = BeanUtil.copyToList(records, UserVO.class);
        PageResult pageResult = new PageResult(result.getTotal(), userVOS);
        return Result.success(pageResult);
    }

    /**
     *  根据id查询用户
     * @param userId 用户id
     * @return 用户信息
     */
    public Result<UserVO> getUserById(Long userId) {
        //获取当前用户信息
        Map<String, Object> currentUser = BaseContext.getCurrentUser();
        Long currentUserId = (Long) currentUser.get(JwtClaimsConstant.USER_ID);
        String currentRoleCode = (String) currentUser.get(JwtClaimsConstant.USER_ROLE);
        //判断是否有权限
        boolean flag = false;
        if (Objects.equals(userId, currentUserId) || RoleCode.SUPER_ADMIN.equalsIgnoreCase(currentRoleCode)) {
            //如果查询的id是自己或者当前用户为超级管理员，则返回true
            flag = true;
        }else if (RoleCode.ADMIN.equalsIgnoreCase(currentRoleCode)){
            //如果是管理员则，只能查询普通用户
            //查询目标用户的权限
            String roleCode = permissionClient.getUserRoleCode(userId);
            //若目用户的权限为普通用户，则返回true
            if (RoleCode.USER.equalsIgnoreCase(roleCode)){
                flag = true;
            }
        }
        if (!flag){
            return Result.error("无权限");
        }
        //查询用户信息
        User user = lambdaQuery()
                .eq(User::getUserId, userId)
                .one();
        if (user == null){
            return Result.error("用户不存在");
        }
        //封装并返回
        UserVO userVO = new UserVO();
        userVO.setUserId(user.getUserId());
        userVO.setUsername(user.getUsername());
        userVO.setEmail(user.getEmail());
        userVO.setPhone(user.getPhone());
        userVO.setGmtCreate(user.getGmtCreate());
        return Result.success(userVO);
    }

    /**
     * 根据id修改用户信息
     * @param userId 用户id
     * @param updateDTO 修改信息
     * @return 是否成功
     */
    public Result<String> updateUser(Long userId, UpdateDTO updateDTO) {
        //获取当前用户信息
        Map<String, Object> currentUser = BaseContext.getCurrentUser();
        Long currentUserId = (Long) currentUser.get(JwtClaimsConstant.USER_ID);
        String currentRoleCode = (String) currentUser.get(JwtClaimsConstant.USER_ROLE);
        //查询用户是否存在
        User user = lambdaQuery()
                .eq(User::getUserId, userId)
                .one();
        if (user == null){
            return Result.error("用户不存在");
        }
        //修改用户信息
        user.setEmail(updateDTO.getEmail());
        user.setPhone(updateDTO.getPhone());
        if (Objects.equals(userId, currentUserId) || RoleCode.SUPER_ADMIN.equalsIgnoreCase(currentRoleCode)){
            //如果修改的是自己或者当前用户为超级管理员，则修改用户信息
            updateById(user);
            return Result.success("修改成功");
        }else if (RoleCode.ADMIN.equalsIgnoreCase(currentRoleCode)){
            //如果是管理员则，只能修改普通用户
            //查询目标用户的权限
            String roleCode = permissionClient.getUserRoleCode(userId);
//            若目用户的权限为普通用户，则修改用户信息
            if (RoleCode.USER.equalsIgnoreCase(roleCode)){
                updateById(user);
                return Result.success("修改成功");
            }
        }
        return Result.error("无修改权限");
    }

    /**
     * 重置密码
     * @param resetPasswordDTO 重置密码相关数据
     * @return 是否成功
     */
    public Result<String> resetPassword(ResetPasswordDTO resetPasswordDTO) {
        //获取当前用户信息
        Map<String, Object> currentUser = BaseContext.getCurrentUser();
        Long currentUserId = (Long) currentUser.get(JwtClaimsConstant.USER_ID);
        String currentRoleCode = (String) currentUser.get(JwtClaimsConstant.USER_ROLE);
        User user = lambdaQuery()
                .eq(User::getUserId, resetPasswordDTO.getUserId())
                .one();
        if (user == null) {
            return Result.error("用户不存在");
        }
        user.setPassword(DigestUtils.md5DigestAsHex(resetPasswordDTO.getPassword().getBytes()));
        if (Objects.equals(resetPasswordDTO.getUserId(), currentUserId) || RoleCode.SUPER_ADMIN.equalsIgnoreCase(currentRoleCode)){
            //如果修改的是自己或者当前用户为超级管理员，则修改用户信息
            updateById(user);
            return Result.success("修改成功");
        }else if (RoleCode.ADMIN.equalsIgnoreCase(currentRoleCode)){
            //如果是管理员则，只能修改普通用户
            Long userId =resetPasswordDTO.getUserId();
            String roleCode = permissionClient.getUserRoleCode(userId);
            if (RoleCode.USER.equalsIgnoreCase(roleCode)){
                updateById(user);
                return Result.success("修改成功");
            }
        }
        return Result.error("无修改权限");
    }

    /**
     * 修改权限
     * @param modifyPermissionsDTO 修改权限相关数据
     * @return 是否成功
     */
    @Transactional(rollbackFor = Exception.class)
    @ShardingSphereTransactionType(value = TransactionType.BASE)
    public Result<String> modifyPermissions(ModifyPermissionsDTO modifyPermissionsDTO) {
        //获取当前用户信息
        Map<String, Object> currentUser = BaseContext.getCurrentUser();
        String currentRoleCode = (String) currentUser.get(JwtClaimsConstant.USER_ROLE);
        //如果不是超级管理员，则不允许修改权限
        if (!RoleCode.SUPER_ADMIN.equalsIgnoreCase(currentRoleCode)){
            return Result.error("无修改权限");
        }
        //查询用户是否存在
        Integer count = lambdaQuery()
                .eq(User::getUserId, modifyPermissionsDTO.getUserId())
                .count();
        if (count == 0){
            return Result.error("用户不存在");
        }
        //修改权限
        Long userId = modifyPermissionsDTO.getUserId();
        if (RoleCode.USER.equalsIgnoreCase(modifyPermissionsDTO.getRoleCodes())){
            permissionClient.downgradeToUser(userId);
        }else if (RoleCode.ADMIN.equalsIgnoreCase(modifyPermissionsDTO.getRoleCodes())){
            permissionClient.upgradeToAdmin(userId);
        }
        return Result.success("修改成功");
    }
}
